package com.dalitek.sampleface.q;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.TextureView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RadioGroup;
import android.widget.ScrollView;
import android.widget.Spinner;
import android.widget.TextView;

import com.dalitek.sampleface.BaseActivity;
import com.dalitek.sampleface.LaunchActivity;
import com.dalitek.sampleface.R;
import com.dalitek.sampleface.TestActivity;
import com.dalitek.sampleface._1VNActivity;
import com.dalitek.sampleface.adapter.FaceQueryAdapter;
import com.dalitek.sampleface.view.CameraDetectView;
import com.dalitek.sampleface.view.OverlayEntity;
import com.oliveapp.face.libfacecapture.datatype.FrameData;
import com.oliveapp.face.libfacecapture.q.QFace;
import com.oliveapp.face.libfacecapture.x.entity.Face;
import com.oliveapp.face.libfacecapture.x.entity.FaceEntity;
import com.oliveapp.face.libfacecapture.x.interfaces.CaptureListener;
import com.oliveapp.face.libfacecapture.x.interfaces.FaceAccessListener;
import com.oliveapp.face.libfacecapture.x.interfaces.FrameListener;
import com.oliveapp.face.libfacecapture.x.interfaces.InitListener;
import com.oliveapp.face.libfacecapture.x.interfaces.WatchDogListener;
import com.oliveapp.face.libfacecapture.x.task.ReturnCurrentFrameTask;
import com.oliveapp.face.libfacecapture.x.utils.CameraUtils;
import com.oliveapp.libcommon.utility.FileUtil;
import com.oliveapp.libcommon.utility.LogUtil;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import static com.oliveapp.face.libfacecapture.captor.SessionStatusEnum.SESSION_PASS;
import static com.oliveapp.face.libfacecapture.captor.SessionStatusEnum.SESSION_SINGLE_FRAME_OK;
import static com.oliveapp.face.libfacecapture.datatype.LibFaceCaptureParameters.IMG_PATH;
import static com.oliveapp.libcommon.datatype.ErrorCode.ERROR_PROCESSING;
import static com.oliveapp.libcommon.datatype.ErrorCode.ERROR_SUCCESS;
import static com.oliveapp.libcommon.datatype.ErrorCode.ERROR_SUCCESS_CAMERA;
import static com.oliveapp.libcommon.datatype.ErrorCode.OLIVEAPP_CAMERA_OPEN_ERROR;
import static com.oliveapp.libcommon.utility.LogUtil.VERBOSE;

public class _Q1V1Activity extends BaseActivity implements TextureView.SurfaceTextureListener {
    private static final String TAG = _Q1V1Activity.class.getSimpleName();
    private TextureView visibleCamera;
    private TextureView infraredCamera;


    private static final int VIDEO_WIDTH = captureConfig_1v1.getVideo_width();
    private static final int VIDEO_HEIGHT = captureConfig_1v1.getVideo_height();

    private static final int PAINT_COLOR_FACE = Color.RED;
    private static final int PAINT_COLOR_FACE_PASS = Color.WHITE;

    private boolean useDualCamera = true;

    //摄像头相关
    private Camera mInfraredCamera, mVisibleCamera;
    private int visibleCameraId = captureConfig_1v1.getVisibleCameraId();
    private int infraredCameraId = captureConfig_1v1.getInfraredCameraId();
    //是否自动对焦
    private boolean needAutoFocus = captureConfig_1v1.isNeedAutoFocus();

    private int cameraDegree = captureConfig_1v1.getCameraDegree();
    private int frameDataDegree = captureConfig_1v1.getFrameDataDegree();

    private QFace qFace;
    private InitListener initListener;
    private CaptureListener captureListener;
    private FaceAccessListener faceAccessListener;
    private WatchDogListener watchDogListener;

    private View overlayView;
    private TextView tvTitle,tvResult;
    private AlertDialog addDialog;
    private View btnRegister;
    private View btnQuery;
    private View btnSetting;
    private Handler faceQueryHandler =new Handler();
    private Runnable faceQueryRunnable = () -> {tvResult.setText("");};
    private TextView tvInit;
    private FrameLayout fr_camera;
    private FrameListener frameListener = null;

    private int width;
    private int height;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //打开LOG打印等级
        LogUtil.MIN_LOG_LEVEL = VERBOSE;
        LogUtil.ENABLE_LOG = true;
        LogUtil.e(TAG, "onCreate");

        //设置全屏
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        //设置全屏
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.activity_q);
        Display mDisplay = getWindowManager().getDefaultDisplay();
        width = mDisplay.getWidth();
        height = mDisplay.getHeight();
        height = width * VIDEO_WIDTH / VIDEO_HEIGHT;

        initView();
        initEvent();
        initListeners();
        startUp();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(qFace!=null){
            qFace.unInit();
            qFace = null;
        }
    }

    @Override
    protected void onRestart() {
        super.onRestart();
    }

    private void initView() {
        overlayView = findViewById(R.id.back_view);
        tvTitle = findViewById(R.id.tv_title);
        tvInit = findViewById(R.id.tv_init);
        tvResult = findViewById(R.id.tv_result);
        btnRegister = findViewById(R.id.btn_register);
        btnQuery = findViewById(R.id.btn_query);
        btnSetting = findViewById(R.id.btn_setting);
        fr_camera = findViewById(R.id.fr_camera);
        LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,height);
        fr_camera.setLayoutParams(layoutParams);
        visibleCamera = findViewById(R.id.visible_camera);
        infraredCamera = findViewById(R.id.infrared_camera);
        visibleCamera.setSurfaceTextureListener(this);
        infraredCamera.setSurfaceTextureListener(this);
    }
    private void initEvent() {
        findViewById(R.id.btn_back).setOnClickListener(view -> {
            closeCamera();
            startActivity(new Intent(bContext,LaunchActivity.class));
            finish();
        });
        final int[] tmpFaceRectScaleX = {captureConfig_1v1.getScaleX()};
        final boolean[] tmpNeedAutoFocus = {captureConfig_1v1.isNeedAutoFocus()};
        btnSetting.setOnClickListener(view -> {
            dismissLoadingDialog();
            if( addDialog!=null && addDialog.isShowing()) addDialog.dismiss();
            addDialog = new AlertDialog.Builder(this)
                    .setNegativeButton("取消", (dialogInterface, i) -> {
                        dismissLoadingDialog();
                        addDialog.dismiss();
                    }).create();
            ScrollView scrollView = (ScrollView) LayoutInflater.from(bContext).inflate(R.layout.dialog_setting,null);

            //设置激活License
            scrollView.findViewById(R.id.btn_activate_license).setOnClickListener(view15 -> qFace.activateLicense(activateCode,(rtn, message) -> {
                toast(message);
            }));

            //设置验证License激活状态
            scrollView.findViewById(R.id.btn_verify_license).setOnClickListener(view14 -> {
                toast(qFace.verifyLicense()?"已激活":"未激活");
            });

            //设置重置清除License
            scrollView.findViewById(R.id.btn_clear_license).setOnClickListener(view1 -> {
                qFace.clearLicense();
                toast("清除License成功!");
            });

            //设置重置人脸抓拍算法
            scrollView.findViewById(R.id.btn_reset_captor).setOnClickListener(view12 -> {
                qFace.reInitCaptor();
                addDialog.dismiss();
            });

            //设置重置人脸对比算法
            scrollView.findViewById(R.id.btn_reset_verify).setOnClickListener(view13 -> {
                qFace.reInitVerify();
                addDialog.dismiss();
            });

            //设置跳转至三方Activity
            scrollView.findViewById(R.id.btn_test).setOnClickListener(view6 -> {
                startActivity(new Intent(bContext, TestActivity.class));
                addDialog.dismiss();
            });

            //人脸识别阈值设置
            Spinner verifyThresholdSpinner = scrollView.findViewById(R.id.sp_verify_threshold);
            String[] verifyThresholds =  {"10","20","40","80","90"};//范围0~100连续值
            verifyThresholdSpinner.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, verifyThresholds));
            verifyThresholdSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
                    if(i!=getIntArrayPosition(verifyThresholds, qFace.getThreshold())){
                        qFace.setThreshold(Integer.parseInt(verifyThresholds[i]));
                        addDialog.dismiss();
                    }
                }

                @Override
                public void onNothingSelected(AdapterView<?> adapterView) {

                }
            });
            verifyThresholdSpinner.setSelection(getIntArrayPosition(verifyThresholds, qFace.getThreshold()));


            //设置打开活体
            scrollView.findViewById(R.id.btn_live_open).setOnClickListener(view16 -> {
                qFace.setUseDualCamera(true);
                useDualCamera = true;
                infraredCamera.setVisibility(View.VISIBLE);
                openCamera();
                qFace.reInitCaptor();
                addDialog.dismiss();
            });

            //设置关闭活体
            scrollView.findViewById(R.id.btn_live_close).setOnClickListener(view16 -> {
                qFace.setUseDualCamera(false);
                useDualCamera = false;
                infraredCamera.setVisibility(View.GONE);
                openCamera();
                qFace.reInitCaptor();
                addDialog.dismiss();
            });

            //设置活体等级，单目模式默认零级，设置无效
            Spinner liveLevelSpinner = scrollView.findViewById(R.id.sp_live_level);
            String[] liveLevels = {"零级","一级","二级","三级"};
            liveLevelSpinner.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, liveLevels));
            liveLevelSpinner.setSelection(qFace.getCaptureSecureLevel());
            liveLevelSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
                    if(i!=qFace.getCaptureSecureLevel()){
                        qFace.setCaptureSecureLevel(i);
                        qFace.reInitCaptor();
                        addDialog.dismiss();
                    }
                }

                @Override
                public void onNothingSelected(AdapterView<?> adapterView) {

                }
            });

            //人像抓拍占镜头最小比率 可根据此设置制作识别距离控制逻辑
            Spinner faceRatioMinSpinner = scrollView.findViewById(R.id.sp_face_ratio_min);
            String[] faceRatioMins =  {"0","0.3","0.5","0.7","1.0"};//范围0~1连续值
            faceRatioMinSpinner.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, faceRatioMins));
            faceRatioMinSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
                    if(i!=getDoubleArrayPosition(faceRatioMins, qFace.getMinFaceRatio())){
                        qFace.setMinFaceRatio(Double.parseDouble(faceRatioMins[i]));
                        qFace.reInitCaptor();
                        addDialog.dismiss();
                    }
                }

                @Override
                public void onNothingSelected(AdapterView<?> adapterView) {

                }
            });
            faceRatioMinSpinner.setSelection(getDoubleArrayPosition(faceRatioMins, qFace.getMinFaceRatio()));

            //设置相机旋转角度
            RadioGroup rgCameraDegree = scrollView.findViewById(R.id.rg_camera_degree);
            switch (cameraDegree){
                case 0 :
                    rgCameraDegree.check(R.id.rb_camera_degree_0);
                    break;
                case 90 :
                    rgCameraDegree.check(R.id.rb_camera_degree_90);
                    break;
                case 180 :
                    rgCameraDegree.check(R.id.rb_camera_degree_180);
                    break;
                case 270 :
                    rgCameraDegree.check(R.id.rb_camera_degree_270);
                    break;
            }
            rgCameraDegree.setOnCheckedChangeListener((radioGroup, i) -> {
                switch (i){
                    case R.id.rb_camera_degree_0:
                        cameraDegree = 0;
                        break;
                    case R.id.rb_camera_degree_90:
                        cameraDegree = 90;
                        break;
                    case R.id.rb_camera_degree_180:
                        cameraDegree = 180;
                        break;
                    case R.id.rb_camera_degree_270:
                        cameraDegree = 270;
                        break;
                }
                openCamera();
                addDialog.dismiss();
            });

            //设置帧数据旋转角度
            RadioGroup rgFrameDataDegree = scrollView.findViewById(R.id.rg_frame_data_degree);
            switch (qFace.getFrameDataDegree()){
                case 0 :
                    rgFrameDataDegree.check(R.id.rb_frame_data_degree_0);
                    break;
                case 90 :
                    rgFrameDataDegree.check(R.id.rb_frame_data_degree_90);
                    break;
                case 180 :
                    rgFrameDataDegree.check(R.id.rb_frame_data_degree_180);
                    break;
                case 270 :
                    rgFrameDataDegree.check(R.id.rb_frame_data_degree_270);
                    break;
            }
            rgFrameDataDegree.setOnCheckedChangeListener((radioGroup, i) -> {
                switch (i){
                    case R.id.rb_frame_data_degree_0:
                        qFace.setFrameDataDegree(0);
                        break;
                    case R.id.rb_frame_data_degree_90:
                        qFace.setFrameDataDegree(90);
                        break;
                    case R.id.rb_frame_data_degree_180:
                        qFace.setFrameDataDegree(180);
                        break;
                    case R.id.rb_frame_data_degree_270:
                        qFace.setFrameDataDegree(270);
                        break;
                }
                qFace.reInitCaptor();
                addDialog.dismiss();
            });

            //人脸框镜像开启
            CheckBox cbFaceRectScaleX = scrollView.findViewById(R.id.cb_face_rect_scale_x);
            cbFaceRectScaleX.setChecked( tmpFaceRectScaleX[0] == -1);
            cbFaceRectScaleX.setOnCheckedChangeListener((compoundButton, b) -> {
                tmpFaceRectScaleX[0] = b?-1:1;
                ((CameraDetectView)overlayView).init(VIDEO_WIDTH, VIDEO_HEIGHT,height,width,tmpFaceRectScaleX[0]);
                addDialog.dismiss();
            });

            //自动对焦启用(变焦摄像头有效)
            CheckBox cbNeedAutoFocus = scrollView.findViewById(R.id.cb_need_auto_focus);
            cbNeedAutoFocus.setChecked(tmpNeedAutoFocus[0]);
            cbNeedAutoFocus.setOnCheckedChangeListener((compoundButton, b) -> {
                tmpNeedAutoFocus[0] = b;
                needAutoFocus = b;
                openCamera();
                addDialog.dismiss();
            });

            //设置可见光摄像头id
            RadioGroup rgCameraVisible = scrollView.findViewById(R.id.rg_camera_visible);
            switch (visibleCameraId){
                case 0 :
                    rgCameraVisible.check(R.id.rb_camera_visible_0);
                    break;
                case 1 :
                    rgCameraVisible.check(R.id.rb_camera_visible_1);
                    break;
                case 2 :
                    rgCameraVisible.check(R.id.rb_camera_visible_2);
                    break;
                case 3 :
                    rgCameraVisible.check(R.id.rb_camera_visible_3);
                    break;
            }
            rgCameraVisible.setOnCheckedChangeListener((radioGroup, i) -> {
                switch (i){
                    case R.id.rb_camera_visible_0:
                        visibleCameraId = 0;
                        break;
                    case R.id.rb_camera_visible_1:
                        visibleCameraId = 1;
                        break;
                    case R.id.rb_camera_visible_2:
                        visibleCameraId = 2;
                        break;
                    case R.id.rb_camera_visible_3:
                        visibleCameraId = 3;
                        break;
                }
                openCamera();
                addDialog.dismiss();
            });
            //设置红外摄像头id
            RadioGroup rgCameraInfrared = scrollView.findViewById(R.id.rg_camera_infrared);
            switch (infraredCameraId){
                case 0 :
                    rgCameraInfrared.check(R.id.rb_camera_infrared_0);
                    break;
                case 1 :
                    rgCameraInfrared.check(R.id.rb_camera_infrared_1);
                    break;
                case 2 :
                    rgCameraInfrared.check(R.id.rb_camera_infrared_2);
                    break;
                case 3 :
                    rgCameraInfrared.check(R.id.rb_camera_infrared_3);
                    break;
            }
            rgCameraInfrared.setOnCheckedChangeListener((radioGroup, i) -> {
                switch (i){
                    case R.id.rb_camera_infrared_0:
                        infraredCameraId = 0;
                        break;
                    case R.id.rb_camera_infrared_1:
                        infraredCameraId = 1;
                        break;
                    case R.id.rb_camera_infrared_2:
                        infraredCameraId = 2;
                        break;
                    case R.id.rb_camera_infrared_3:
                        infraredCameraId = 3;
                        break;
                }

                qFace.reInitCaptor();
                addDialog.dismiss();
            });
            addDialog.setView(scrollView);
            addDialog.show();

        });
        btnRegister.setOnClickListener(view -> {
            showLoadingDialog();
            if( addDialog!=null && addDialog.isShowing()) addDialog.dismiss();
            addDialog = new AlertDialog.Builder(this)
                    .setNegativeButton("取消", (dialogInterface, i) -> {
                        dismissLoadingDialog();
                        addDialog.dismiss();
                    }).create();
            getCurrentFrame(frame -> {
                if(frame!=null){
                    LinearLayout linearLayout = (LinearLayout) LayoutInflater.from(bContext).inflate(R.layout.dialog_register,null);
                    ImageView imgView = linearLayout.findViewById(R.id.iv);
                    TextView tvUserId = linearLayout.findViewById(R.id.tv_user_id);
                    TextView tvUserName = linearLayout.findViewById(R.id.tv_user_name);
                    imgView.setImageBitmap(BitmapFactory.decodeByteArray(frame, 0, frame.length));
                    imgView.setScaleX(-1);
                    List<Face> currentList = qFace.listAllFaces();
                    int minId = 0;
                    for(Face face : currentList){
                        try {
                            if(Integer.parseInt(face.getUserid())>minId){
                                minId = Integer.parseInt(face.getUserid());
                            }
                        }catch (Exception e){
                            continue;
                        }
                    }

                    //保存byte[]图片到本地
                    File faceFileDir = new File(IMG_PATH);
                    if (!faceFileDir.exists()){
                        try {
                            FileUtil.createDir(faceFileDir);
                        } catch (IOException e) {
                            e.printStackTrace();
                            dismissLoadingDialog();
                            return;
                        }
                    }
                    String userId = String.valueOf(minId+1);
                    String userName = "用户"+userId;
                    String faceFileName = new StringBuilder()
                            .append(IMG_PATH)
                            .append(userId)
                            .append("_")
                            .append(userName)
                            .append(".png")
                            .toString();
                    File faceFile = new File(faceFileName);
                    try {
                        FileUtil.writeByteToFile(faceFile,frame,false,true);
                    } catch (IOException e) {
                        e.printStackTrace();
                        dismissLoadingDialog();
                        return;
                    }


                    tvUserId.setText(userId);
                    tvUserName.setText(userName);
                    Face face = new Face()
                            .setUserid(userId)
                            .setUsername(userName)
                            .setFacetype(1)
                            .setFace(faceFileName)
                            .setFeature(frame);

                    dismissLoadingDialog();

                    addDialog.setButton(DialogInterface.BUTTON_POSITIVE, "注册", (dialogInterface, i) -> {
                        showLoadingDialog();
                        if( addDialog.isShowing()) addDialog.dismiss();
                        qFace.setIdCardFace(face);
                        toast("身份证信息已添加");
                        dismissLoadingDialog();
                    });
                    addDialog.setView(linearLayout);
                    addDialog.show();
                    addDialog.getButton(DialogInterface.BUTTON_NEGATIVE).setTextColor(Color.GRAY);
                }
            });
        });

        btnQuery.setOnClickListener(view -> {
            showLoadingDialog();
            ListView listView = (ListView) getLayoutInflater().inflate(R.layout.dialog_query_list, null);
            List<Face> faces = new ArrayList<>();
            AlertDialog alertDialog = new AlertDialog.Builder(this).setTitle("人员列表"+"("+faces.size()+")")
                    .setView(listView)
                    .setPositiveButton("返回", (paramAnonymousDialogInterface, paramAnonymousInt) -> {

                    }).create();
            FaceQueryAdapter adapter = new FaceQueryAdapter(bContext, faces, qFace,alertDialog,captureConfig_1v1.getCaptureType());
            listView.setAdapter(adapter);
            faces.clear();
            faces.addAll(qFace.getIdcardFace());
            adapter.notifyDataSetChanged();
            alertDialog.setTitle("人员列表"+"("+faces.size()+")");
            alertDialog.show();
            dismissLoadingDialog();
        });
    }
    private void initListeners() {
        initListener = (rtn, message) -> {
            switch (rtn){
                case ERROR_SUCCESS:
                    toast("初始化成功!");
                    LogUtil.e(TAG,"startUp Success");
                    tvInit.setText("初始化成功!");
                    tvInit.setVisibility(View.GONE);
                    initOverlay();
                    break;
                case ERROR_SUCCESS_CAMERA://摄像头初始化成功
                    initOverlay();
                case ERROR_PROCESSING:
                    LogUtil.e(TAG,"startUp-->"+message);
                    tvInit.setText(message);
                    break;
                default:
                    toast("初始化失败("+rtn+"):"+message);
                    tvInit.setText("初始化失败("+rtn+")\n"+message);
                    LogUtil.e(TAG,"startUp Fail-->"+rtn+"-->"+message);
                    break;
            }
        };
        captureListener = faceEntityList -> {
            List<OverlayEntity> overlayEntityList = new ArrayList<>();
            for(FaceEntity faceEntity :faceEntityList){
                OverlayEntity overlayEntity = new OverlayEntity();
                overlayEntity.setRect(faceEntity.getVisibleFaceRect());
                //绘制人脸框
                int paintColor;
                switch (faceEntity.getSessionStatus()){
                    case SESSION_PASS:
                    case SESSION_SINGLE_FRAME_OK:
                        paintColor = PAINT_COLOR_FACE_PASS;
                        break;
                    default:
                        paintColor = PAINT_COLOR_FACE;
                }
                overlayEntity.setPaintColor(paintColor);
                overlayEntityList.add(overlayEntity );
                runOnUiThread(() -> {
                            if(faceEntity.getSessionStatus()!=SESSION_PASS)tvTitle.setText(faceEntity.getSessionTitle());
                        }
                );
            }
//        LogUtil.e(TAG, Arrays.toString(faceEntityList.toArray()));
            ((CameraDetectView)overlayView).setValue(overlayEntityList);
            overlayView.postInvalidate();
        };
        faceAccessListener = (faceList, spend) -> {
            if(faceList.size()>0){
                StringBuilder stringBuilder = new StringBuilder();
                for (Face face :
                        faceList) {
                    stringBuilder
                            .append(face.getUserid())
                            .append("_")
                            .append(face.getUsername())
                            .append("_").append(face.getSimilarity())
                            .append("%")
                            .append(" ");
                }
                if(stringBuilder.length()>0) {
                    stringBuilder.append(spend).append("ms");
                    runOnUiThread(() -> tvResult.setText(stringBuilder.toString()));
                    faceQueryHandler.removeCallbacks(faceQueryRunnable);
                    faceQueryHandler.postDelayed(faceQueryRunnable, 2000);
                }
            }
        };
        watchDogListener = watchDogEvent -> {
            LogUtil.e(TAG,watchDogEvent.toString());
        };
    }
    private int getDoubleArrayPosition(String[] array, double value) {
        int position = 0;
        for (int i = 0; i < array.length; i++) {
            if (Double.parseDouble(array[i]) == value) {
                position = i;
            }
        }
        return position;
    }
    private int getIntArrayPosition(String[] array, int value) {
        int position = 0;
        for (int i = 0; i < array.length; i++) {
            if (Integer.parseInt(array[i]) == value) {
                position = i;
            }
        }
        return position;
    }

    /**
     * 设置可见光单帧监听器
     * @param frameListener
     * @return
     */
    public void setFrameListener(FrameListener frameListener) {
        this.frameListener = frameListener;
    }
    /**
     * 获取当前帧
     */
    public void getCurrentFrame(FrameListener frameListener){
        setFrameListener(frameListener);
        statusGetFrame = true;
    }

    /**
     * 返回当前帧
     * @param visibleByte
     */
    public void returnCurrentFrame(final byte[] visibleByte){
        statusGetFrame = false;
        new ReturnCurrentFrameTask()
                .setFormat(mVisibleCamera.getParameters().getPreviewFormat())
                .setWidth(mVisibleCamera.getParameters().getPreviewSize().width)
                .setHeight(mVisibleCamera.getParameters().getPreviewSize().height)
                .setVisibleByte(visibleByte)
                .setFrameDataDegree(frameDataDegree)
                .setFrameListener(frameListener)
                .execute();
    }

    private void startUp() {
        qFace = QFace.getInstance()
                .setContext(bContext)
                .setCaptureListener(captureListener)//必须
                .setFaceAccessListener(faceAccessListener)//必须
                .setInitListener(initListener)//必须
                .setVideo_width(VIDEO_WIDTH)//必须
                .setVideo_height(VIDEO_HEIGHT)//必须
                .setUseDualCamera(captureConfig_1v1.isUseDualCamera())//是否双目，可选，默认双目true
                .setCaptureSecureLevel(captureConfig_1v1.getCaptureSecureLevel())//活体安全等级0~3
                .setMinFaceRatio(captureConfig_1v1.getMinFaceRatio())//最小人脸比率
                .setFrameDataDegree(captureConfig_1v1.getFrameDataDegree())//帧数据内容角度
                .setCaptureType(captureConfig_1v1.getCaptureType())//必填 0:1v1 , 1:1vn , 2:nvn
                .setVerifyInstanceNum(captureConfig_1v1.getVerifyInstanceNum())
                .setEnableWatchDog(true)
                .setAutoRecovery(true)
                .setWatchDogListener(watchDogListener);
    }

    //初始化绘制人脸框VIEW
    private void initOverlay() {
        ((CameraDetectView)overlayView).init(VIDEO_WIDTH, VIDEO_HEIGHT,height,width,captureConfig_1v1.getScaleX());
    }


    private final Object mLock = new Object();
    // 组装frame
    private static byte[] mInfraredData;
    private static byte[] mVisibleData;
    private static boolean isInfraredDataSet = false;
    private static boolean isVisibleDataSet = false;
    private int mFrameId = 0;

    // 跳帧间隔数量
    private int frame_jump_nums = 1;


    private boolean statusGetFrame = false;
    /**
     * 摄像头的回调
     */
    Camera.PreviewCallback previewCallback = new Camera.PreviewCallback() {
        @Override
        public void onPreviewFrame(byte[] data, Camera camera) {
            if(statusGetFrame && mVisibleCamera == camera){
                returnCurrentFrame(data);
            }
            if(qFace.frameList.size() == 0 ){
                //将数据进行检测
                long timestamp = System.currentTimeMillis();
                if (useDualCamera) {
                    synchronized (mLock) {
                        if (mVisibleCamera == camera) {
                            mVisibleData = data;
                            isVisibleDataSet = true;
                        } else if (mInfraredCamera == camera) {
                            mInfraredData = data;
                            isInfraredDataSet = true;
                        } else {
                            throw new IllegalArgumentException("错误的摄像头类型");
                        }

                        if (isVisibleDataSet && isInfraredDataSet) {
                            isInfraredDataSet = false;
                            isVisibleDataSet = false;

                            if(mFrameId % frame_jump_nums ==0 ){
                                FrameData frameData = new FrameData();
                                frameData.visible = mVisibleData;
                                frameData.infrared = mInfraredData;
                                frameData.frameId = mFrameId;
                                frameData.capturedTime = timestamp;
                                qFace.frameList.offer(frameData);

                            }

                            mFrameId += 1;
                        }
                    }
                } else {
                    if(mFrameId % frame_jump_nums == 0){
                        FrameData frameData = new FrameData();
                        frameData.infrared = data;
                        frameData.visible = data;
                        frameData.frameId = mFrameId;
                        frameData.capturedTime = timestamp;
                        qFace.frameList.offer(frameData);
                    }
                    mFrameId += 1;
                }
            }

        }
    };
    private int openCamera() {
        LogUtil.e(TAG,"openCamera");
        closeCamera();
        int numCameras = Camera.getNumberOfCameras();
        if(useDualCamera){//双目模式
            if (numCameras < 2) {
                LogUtil.e(TAG, "[openCamera] failed: less than two cameras");
                return OLIVEAPP_CAMERA_OPEN_ERROR;
            }

            if (mInfraredCamera != null || mVisibleCamera != null) {
                LogUtil.w(TAG, "Camera has not been released. Now release all cameras.");
                closeCamera();
            }

            //打开可见光摄像头
            try {
                mVisibleCamera = Camera.open(visibleCameraId);
                Camera.Parameters params = mVisibleCamera.getParameters();
                CameraUtils.choosePreviewSize(params, VIDEO_WIDTH, VIDEO_HEIGHT);
                CameraUtils.chooseFixedPreviewFps(params, 30 * 1000);
                if(this.needAutoFocus)
                    params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
                mVisibleCamera.setParameters(params);
                mVisibleCamera.setDisplayOrientation(cameraDegree);
            } catch (Exception e) {
                Log.e(TAG, e.getLocalizedMessage());
                return OLIVEAPP_CAMERA_OPEN_ERROR;
            }

            //打开红外摄像头
            try {
                mInfraredCamera = Camera.open(infraredCameraId);
                Camera.Parameters parms = mInfraredCamera.getParameters();
                CameraUtils.choosePreviewSize(parms, VIDEO_WIDTH, VIDEO_HEIGHT);
                CameraUtils.chooseFixedPreviewFps(parms, 30 * 1000);
                if(this.needAutoFocus)
                    parms.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
                mInfraredCamera.setParameters(parms);
                mInfraredCamera.setDisplayOrientation(cameraDegree);
            } catch (Exception e) {
                Log.e(TAG, e.getLocalizedMessage());
                return OLIVEAPP_CAMERA_OPEN_ERROR;
            }

            //设置回显控件
            try {
                mVisibleCamera.setPreviewTexture(visibleCamera.getSurfaceTexture());
                mInfraredCamera.setPreviewTexture(infraredCamera.getSurfaceTexture());
            } catch (IOException e) {
                LogUtil.e(TAG, "openCamera: exception" + e.toString());
                return OLIVEAPP_CAMERA_OPEN_ERROR;
            }

            mInfraredCamera.startPreview();
            mVisibleCamera.startPreview();

            mVisibleCamera.setPreviewCallback(previewCallback);
            mInfraredCamera.setPreviewCallback(previewCallback);
        }else {//单目模式
            if (mVisibleCamera != null) {
                LogUtil.w(TAG, "Camera has not been released. Now release all cameras.");
                closeCamera();
            }

            mVisibleCamera = Camera.open(visibleCameraId);
            Camera.Parameters params = mVisibleCamera.getParameters();
            CameraUtils.choosePreviewSize(params, VIDEO_WIDTH, VIDEO_HEIGHT);
            CameraUtils.chooseFixedPreviewFps(params, 30 * 1000);
            if(this.needAutoFocus)
                params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
            mVisibleCamera.setParameters(params);
            mVisibleCamera.setDisplayOrientation(cameraDegree);


            try {
                mVisibleCamera.setPreviewTexture(visibleCamera.getSurfaceTexture());
            } catch (IOException e) {
                LogUtil.e(TAG, "openCamera: exception" + e.toString());
                return OLIVEAPP_CAMERA_OPEN_ERROR;
            }
            mVisibleCamera.startPreview();
            mVisibleCamera.setPreviewCallback(previewCallback);
        }
        initListener.onInit(ERROR_SUCCESS_CAMERA,"摄像头初始化成功");
        return ERROR_SUCCESS;
    }


    private void closeCamera() {
        if (mInfraredCamera != null) {
            mInfraredCamera.stopPreview();
            mInfraredCamera.setPreviewCallback(null);
            mInfraredCamera.release();
            mInfraredCamera = null;
        }

        if (mVisibleCamera != null) {
            mVisibleCamera.stopPreview();
            mVisibleCamera.setPreviewCallback(null);
            mVisibleCamera.release();
            mVisibleCamera = null;
        }
    }
    private boolean hasInitVisible = false;
    private boolean hasInitInfrared = false;
    private final Object cameraInitObj = new Object();
    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i1) {
        if(useDualCamera){
            synchronized (cameraInitObj){
                if(visibleCamera.getSurfaceTexture() == surfaceTexture){
                    hasInitVisible = true;
                }
                if(infraredCamera.getSurfaceTexture() == surfaceTexture){
                    hasInitInfrared = true;
                }
                if(hasInitVisible && hasInitInfrared){
                    int rtn = openCamera();
                    if(rtn == ERROR_SUCCESS){
                        qFace.init();
                    }else{
                        initListener.onInit(rtn,"摄像头初始化失败!");
                    }
                    hasInitVisible = false;
                    hasInitInfrared = false;
                }
            }
        }else{
            if(visibleCamera.getSurfaceTexture() == surfaceTexture){
                int rtn = openCamera();
                if(rtn == ERROR_SUCCESS){
                    qFace.init();
                }else{
                    initListener.onInit(rtn,"摄像头初始化失败!");
                }
            }
        }
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i1) {

    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
        closeCamera();
        return false;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {

    }
}
